#ifndef __M_BENCH_H__
#define __M_BENCH_H__

#include "../log/log.hpp"

void bench(const std::string loggerName,size_t thread_count,size_t msg_len,size_t msg_count)
{
    //1.获取日志器
    log::logger::ptr logger = log::GetLogger(loggerName);//获取日志器
    assert(logger.get());//判断是否为空
    //2.获取指定长度的日志信息
    std::string message(msg_len,'A');//少一个字符,是为了给末尾添加换行
    //3.创建指定数量的线程
    std::cout << "输入线程数量" << thread_count << std::endl;
    std::cout << "输出日志数量" << msg_count << std::endl;
    std::cout << "输出日志总大小" << msg_len * msg_count / 1024 << "KB" << std::endl;
    std::vector<std::thread> threads;//一大批线程
    size_t thread_msg_num = msg_count / thread_count;//每个线程需要输出的日志信息数量
    std::vector<double> const_time(thread_count);//记录各个线程的输出日志时间
    for(int i = 0; i < thread_count; ++i)//遍历所有线程
    {
        threads.emplace_back([&,i]{
            //4.开始计时
            auto start = std::chrono::high_resolution_clock::now();
            //5.开始写日志
            for(int j = 0; j < thread_msg_num; ++j)
            {
                logger->FATAL("%s",message.c_str());
            }
            //5.计时结束
            auto end = std::chrono::high_resolution_clock::now();
            auto con_time = std::chrono::duration_cast<std::chrono::duration<double>>(end - start);//计算输出时间
            const_time[i] = con_time.count();//保存
            auto avg = thread_msg_num / const_time[i];//平均输出一条日志占用的时间
            std::cout << "线程" << i << "耗时" << const_time[i] << "s";
            std::cout << "平均每秒" << (size_t)avg << "条" << std::endl;
        });
    }
    for(int i = 0; i < thread_count; ++i)
    {
        threads[i].join();
    }
    double max_const = 0;//计算总耗时
    for(auto con_time : const_time)
    {
        //6.计算总耗时,在多线程中,每个线程都会消耗时间,但是线程并发处理,因此耗时最高的那个就是总时间
        max_const = con_time > max_const ? con_time : max_const;
    }
    std::cout << "总消耗时间" << max_const << "s" << std::endl;
    std::cout << "平均每秒输出" << (size_t)(msg_len * msg_count / max_const) / 1024 << "KB" << std::endl;
}

void sync_bench_thread_log(size_t thread_count,size_t msg_count,size_t msg_len)
{
    static int num = 1;
    std::string logger_name = "sync_logger_log" + std::to_string(num++);
    LOGI("***********************************************************");
    LOGI("同步日志测试 %d thread , %d message",thread_count,msg_count);
    log::logger::BuliderLogger::ptr Build(new log::GlobalBuildLogger);
    Build->BuilderType(log::logger::Type::LOGGER_SYNCH);
    Build->BuilderLoggerName(logger_name);
    Build->BuilderFormat("%m%n");
    Build->BuilderSinks<log::FileSink>("./FileLog/SyncFile");
    Build->Build();
    bench(logger_name,thread_count,msg_len,msg_count);
    LOGI("***********************************************************");
}

void async_bench_thread_log(size_t thread_count,size_t msg_count,size_t msg_len)
{
    static int num = 1;
    std::string logger_name = "async_logger_log" + std::to_string(num++);
    LOGI("***********************************************************");
    LOGI("同步日志测试 %d thread , %d message",thread_count,msg_count);
    log::logger::BuliderLogger::ptr Build(new log::GlobalBuildLogger);
    Build->BuilderType(log::logger::Type::LOGGER_ASYNCH);
    Build->BuilderFormat("%m%n");
    Build->BuilderLoggerName(logger_name);
    Build->BuilderSinks<log::FileSink>("./FileLog/AsyncFile");
    Build->Build_AsyncWorker_UnSafeType();//开启非安全模式,排除实际落地设计
    Build->Build();
    bench(logger_name,thread_count,msg_len,msg_count);
    LOGI("***********************************************************");
}

#endif